package im.eg.test;

import im.eg.service.OrderService;
import im.eg.service.StudentService;
import im.eg.service.UserMapper;
import im.eg.service.UserService;
import im.eg.spring.AppConfig;
import im.eg.spring.EgApplicationContext;

public class T1 {
    public static void main(String[] args) {
        EgApplicationContext context = new EgApplicationContext(AppConfig.class);
        //UserService userService = (UserService) context.getBean("userService");
        //userService.test();
        //UserMapper userMapper = (UserMapper) context.getBean("userMapper");
        //userMapper.test();
        //OrderService orderService = (OrderService) context.getBean("orderService");

        System.out.println("======================");
        StudentService studentService = (StudentService) context.getBean("studentService");
        System.out.println(studentService.getStudentById(11111));
        System.out.println(studentService.getStudentById(11111));
        System.out.println(studentService.getStudentById(11111));

    }
}

//TODO 定义 XXXApplicationContext 容器类
//TODO 定义 AppConfig 配置类，代表原生的 spring.xml
//TODO 定义 @ComponentScan 注解修饰 AppConfig，用于指定扫描路径
//TODO 编写组件扫描逻辑
//TODO 定义 @Component、@Scope、@Lazy 等注解实现 scope、懒加载等 bean 特性
//TODO 编写组件创建逻辑
//TODO 实现 getBean 方法
//TODO 实现简单的 @Autowired 功能并配置 required 属性，required默认为true表示如果bean不存在则注入失败，反之不存在时为null
//TODO 实现 BeanNameAware回调接口
//TODO 实现 InitializingBean 接口，将初始化功能暴露给开发者
//TODO 实现 BeanPostProcessor 接口，提供初始化前和初始化后两个回调。重点理解【bean的生命周期】，
// --> 参考 https://blog.csdn.net/riemann_/article/details/118500805, https://cloud.tencent.com/developer/article/1409315
//TODO 参考原生 AOP 梳理实现思路。原理：
// --> 启用@EnableAspectJAutoProxy注解后，会向容器中注册一个BeanPostProcessor实现类，即AnnotationAwareAspectJAutoProxyCreator，
//      猜测该类的主要功能：解析切面逻辑和生成代理对象，一个简单的模拟：
/*
//BeanPostProcessor的postProcessAfterInitialization回调
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {

    // aop模拟 - 1 - 判断bean是否需要进行aop
    if (StrUtil.isNotBlank(beanName) && "studentService".equals(beanName)) {
        return Proxy.newProxyInstance(EgBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                // aop模拟 - 2 - 如需进行aop，则将切面逻辑”放入“代理对象的代理逻辑（这里使用jdk代理做演示，实际情况可能会使用cglib代理）
                long start = System.currentTimeMillis();
                Object result = method.invoke(bean, args);
                long end = System.currentTimeMillis();
                System.out.println(method.getName() + " 执行耗时 " + (end - start) + "ms");
                return result;
            }
        });
    }

    return bean;
}
 */
